package com.sharp.join.tk.mybatis.framework.join.entity;

import com.sharp.join.tk.mybatis.utils.ReflectionUtil;
import lombok.*;

import javax.persistence.Column;
import javax.persistence.Table;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Title: JoinRelationship
 * Description: Copyright: Copyright (c) 2019 Company: BHFAE
 *
 * @author Sharp
 * @date 2022/7/4 15:10
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class JoinRelationship {


    private DbField field1;
    private DbField field2;
    private Type type;

    JoinRelationship(Class<?> clazz1, String fieldName1, Class<?> clazz2, String fieldName2, JoinRelationship.Type type) {
        this();
        Table table1 = clazz1.getAnnotation(Table.class);
        Table table2 = clazz2.getAnnotation(Table.class);
        Field field1 = ReflectionUtil.getField(clazz1, fieldName1);
        Field field2 = ReflectionUtil.getField(clazz2, fieldName2);
        Column column1 = field1.getAnnotation(Column.class);
        Column column2 = field2.getAnnotation(Column.class);
        this.field1 = new DbField(table1.name(), column1.name());
        this.field2 = new DbField(table2.name(), column2.name());
        this.type = type;
    }

    @AllArgsConstructor
    public enum Type {
        /**
         *
         */
        LEFT_JOIN(" LEFT JOIN "),
        RIGHT_JOIN(" RIGHT JOIN "),
        JOIN(" JOIN ");

        @Getter
        @Setter
        private String value;
    }

    public static class Builder {
        private List<JoinRelationship> joinRelationshipList;

        Builder(Class<?> clazz1, String fieldName1, Class<?> clazz2, String fieldName2, JoinRelationship.Type type) {
            this();

            this.joinRelationshipList.add(new JoinRelationship(clazz1, fieldName1, clazz2, fieldName2, type));
        }

        Builder() {
            joinRelationshipList = new ArrayList<>();
        }

        public JoinRelationship.Builder add(Class<?> clazz1, String fieldName1, Class<?> clazz2, String fieldName2, JoinRelationship.Type type) {
            joinRelationshipList.add(new JoinRelationship(clazz1, fieldName1, clazz2, fieldName2, type));
            return this;
        }

        public List<JoinRelationship> build() {
            return joinRelationshipList;
        }
    }
}
